//
// @author 风杨
// @date 22-9-28 上午11:05
// @see <a href="yueny09@163.com">mailTo: yueny09@163.com</a>
//


use std::fmt;
use std::fmt::{Display, Formatter, write};

///////////////////////////////////// 等价于接口
// 使用 trait 关键字来声明一个 trait，后面是 trait 的名字
pub trait ISummary {
    // 在大括号中声明描述实现这个 trait 的类型所需要的行为的方法签名
    // 在方法签名后跟分号，而不是在大括号中提供其实现。
    // trait 体中可以有多个方法：一行一个方法签名且都以分号结尾。
    fn summarize(&self) -> String;

    // 指定一个默认实现
    fn go(&self) -> String {
        format!("(common go...):{}", self.summarize())
    }
}

// 结构体实现
impl ISummary for Tweet {
    fn summarize(&self) -> String {
        format!("Tweet {}: {}", self.username, self.content)
    }

    fn go(&self) -> String {
        format!("(Tweet go...):{}", self.summarize())
    }
}

impl ISummary for NewsArticle {
    fn summarize(&self) -> String {
        format!("NewsArticle {}, by {} ({})",
                self.headline, self.author, self.location)
    }
}

//  定义结构体
pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}

#[derive(Debug, Clone)]
pub struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String,
}

/// 为 Tweet 实现 Display trait
impl Display for Tweet {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        Ok(())
    }
}

/// 为 Tweet 实现 From trait
/// 实现了 From<Dog> trait 后会为你的类型提供 from()、into()、try_from() 和 try_into() 方法，使用 try_from() 和try_into() 方法始终是正确的，
/// 使用 into() 和 try_into()方法时要写上类型注解，否则 Rust 不知道你想转换成什么类型。
impl From<NewsArticle> for Tweet {
    fn from(d: NewsArticle) -> Self {
        Tweet {
            username: d.author,
            content: d.content,
            reply: true,
            retweet: false
        }
    }
}